package weaver.splittable.task;

import org.apache.log4j.Logger;
import weaver.conn.ConnectionPool;
import weaver.conn.WeaverConnection;
import weaver.conn.WeaverStatement;
import weaver.interfaces.schedule.BaseCronJob;
import weaver.splittable.STConfig;
import weaver.splittable.STContext;
import weaver.splittable.biz.STBizDataCleaner;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;

/**
 * 现有表数据定时清理任务
 * 清理掉现有表中的过期数据
 * cron定时任务，在后端集成中心 - 计划任务中配置，建议凌晨执行
 * 凌晨一点执行的 cron表达式：0 0 1 * * ?
 * 此任务执行时，同步任务会停止执行
 * author: YUEYANG 2023-01-16
 */
public class STClearTask extends BaseCronJob {

    private static final Logger LOGGER = Logger.getLogger(STConfig.LOGGER_NAME);

    public static boolean isRunning = false;

    @Override
    public void execute() {
        if (!isRunning) {
            try {
                isRunning = true;
                // 遍历执行业务数据清理器中的清理方法
                for (STBizDataCleaner dataCleaner: STContext.BIZ_DATA_CLEANER()) {
                    dataCleaner.clear();
                }

                // 清理 中间表 中的数据
                Long clearTime = getClearTime();
                clearDataChangeInfo(clearTime);
                clearDataClearInfo(clearTime);

            } catch (Exception e) {
                LOGGER.error("ST SyncTask error:", e);
            } finally {
                isRunning = false;
            }
        }
    }

    private Long getClearTime() {
        int keepTime = Integer.valueOf(STConfig.KEEP_SPLIT_TABLE_TIME);
        Calendar calendar = Calendar.getInstance();
        DateFormat dFormat = new SimpleDateFormat("yyyy-MM-dd");
        calendar.setTime(new java.util.Date());
        calendar.add(calendar.DATE, -keepTime);
        return calendar.getTime().getTime();
    }

    /**
     * 清理数据变动记录表
     * 小于清理日期的数据将被删除
     * @param clearTime 清理日期 时间戳
     */
    private void clearDataChangeInfo(Long clearTime) {
        String clearDataChangeSQL = STContext.SYNC_SQL().clearDataChangeInfo(clearTime);
        boolean isFinished = false;
        while (!isFinished) {
            WeaverConnection connection = null;
            WeaverStatement statement = null;
            try {
                connection = ConnectionPool.getInstance().getConnection();
                statement = (WeaverStatement) connection.createStatement();
                int count = statement.originExecuteUpdate(clearDataChangeSQL);
                if (count < 1000) {
                    isFinished = true;
                }
            } catch (Exception e) {
                LOGGER.error("STClearTask clearDataChangeInfo error:", e);
            } finally {
                if (statement != null) {
                    statement.closeNoException();
                }
                if (connection != null) {
                    ConnectionPool.getInstance().returnConnection(connection);
                }
            }
        }
    }

    /**
     * 清理数据清理记录表
     * 小于清理日期的数据将被删除
     * @param clearTime 清理日期 时间戳
     */
    private void clearDataClearInfo(Long clearTime) {
        String clearDataClearSQL = STContext.SYNC_SQL().clearDataClearInfo(clearTime);
        boolean isFinished = false;
        while (!isFinished) {
            WeaverConnection connection = null;
            WeaverStatement statement = null;
            try {
                connection = ConnectionPool.getInstance().getConnection();
                statement = (WeaverStatement) connection.createStatement();
                int count = statement.originExecuteUpdate(clearDataClearSQL);
                if (count < 1000) {
                    isFinished = true;
                }
            } catch (Exception e) {
                LOGGER.error("STClearTask clearDataClearInfo error:", e);
            } finally {
                if (statement != null) {
                    statement.closeNoException();
                }
                if (connection != null) {
                    ConnectionPool.getInstance().returnConnection(connection);
                }
            }
        }
    }

}
